#!/usr/bin/env python3
# -*- coding: utf-8 -*-

__author__ = 'teffy'

'''
@created on 17-11-8
@poject:python-shoot-game
@author:teffy
'''

import sys, pygame,json
from time import sleep
from bullet import Bullet
from enemy import Enemy

def update_screen(screen, settings, ship, bullets, enemys,stats,play_button,scoreboard):
    screen.fill(settings.bg_color)
    for bullet in bullets.sprites():
        bullet.draw_bullet()
    ship.blitme()
    enemys.draw(screen)
    scoreboard.show_score()

    if not stats.game_active:
        play_button.draw_button()

    pygame.display.flip()

def check_event(settings,screen,ship,bullets,enemys,stats,play_button,scoreboard):
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            check_keydown(event, settings, screen, ship, bullets,stats)
        elif event.type == pygame.KEYUP:
            check_keyup(event, settings, screen, ship, bullets)
        elif event.type == pygame.MOUSEBUTTONDOWN:
            mouse_x, mouse_y = pygame.mouse.get_pos()
            check_play_button(settings,screen,ship,bullets,enemys,stats,play_button,scoreboard, mouse_x, mouse_y)

def check_play_button(settings,screen,ship,bullets,enemys,stats,play_button,scoreboard, mouse_x, mouse_y):
    button_click = play_button.rect.collidepoint(mouse_x,mouse_y)
    if button_click and not stats.game_active:
        settings.initialize_dynamic_settings()
        pygame.mouse.set_visible(False)
        stats.reset_stats()
        stats.game_active = True

        scoreboard.prep_level()
        scoreboard.prep_score()
        scoreboard.prep_high_score()
        scoreboard.prep_ships()

        bullets.empty()
        enemys.empty()

        create_enemy(settings,screen,ship,enemys)
        ship.center_ship()

        play_bg_music(True)

def play_bg_music(play):
    if play:
        pygame.mixer.music.load('./sounds/bg.wav')
        pygame.mixer.music.set_volume(0.5)
        pygame.mixer.music.play(-1) # 无限循环播放
    else:
        pygame.mixer.music.stop()

def check_keyup(event, settings, screen, ship, bullets):
    ship.moving_right = False
    ship.moving_left = False

def check_keydown(event, settings, screen, ship, bullets,stats):
    if event.key == pygame.K_q:
        highscore = {settings.config_high_score_key:stats.high_score}
        with open(settings.config_file,'w') as f:
            json.dump(highscore,f)
        sys.exit()
    elif event.key == pygame.K_RIGHT:
        ship.moving_right = True
    elif event.key == pygame.K_LEFT:
        ship.moving_left = True
    elif event.key == pygame.K_SPACE:
        fire_bullet(bullets, screen, settings, ship)

def fire_bullet(bullets, screen, settings, ship):
    '''开火，射击'''
    if len(bullets) < settings.bullet_max_count:
        new_bullet = Bullet(settings, screen, ship)
        bullets.add(new_bullet)


def update_bullets(screen, settings, ship, bullets,enemys,stats,scoreboard,boomsound):
    '''更新子弹'''
    bullets.update()
    # remove disappear bullet
    for bullet in bullets.copy():
        if bullet.rect.bottom <= 0:
            bullets.remove(bullet)
            # print(len(bullets))
    check_bullet_enemy_collisions(bullets, enemys, screen, settings, ship, stats, scoreboard,boomsound)


def check_high_score(stats, scoreboard):
    if stats.score > stats.high_score:
        stats.high_score = stats.score
        scoreboard.prep_high_score()

def play_boom_sound(boomsound):
    boomsound.play()

def check_bullet_enemy_collisions(bullets, enemys, screen, settings, ship, stats, scoreboard,boomsound):
    '''响应子弹和敌人的碰撞，并删除发生碰撞的子弹和敌人'''
    collisions = pygame.sprite.groupcollide(bullets, enemys, True, True)
    if collisions:
        play_boom_sound(boomsound)
        for enemys in collisions.values():
            stats.score += settings.enemy_point * len(enemys)
            scoreboard.prep_score()
        check_high_score(stats,scoreboard)

    start_new_level(bullets, enemys, scoreboard, screen, settings, ship, stats)


def start_new_level(bullets, enemys, scoreboard, screen, settings, ship, stats):
    '''升级'''
    if len(enemys) == 0:  # 敌人消灭完了
        bullets.empty()
        stats.level += 1
        scoreboard.prep_level()
        settings.increase_speed()
        create_enemy(settings, screen, ship, enemys)


def get_number_enemy_x(settings, enemy_width):
    '''获取x轴上可以有多少个敌人'''
    available_space_x = settings.screen_width - enemy_width * 2
    number_enemy_x = int(available_space_x / (enemy_width * 2))
    return number_enemy_x


def get_number_rows(settings, enemy_height, ship_height):
    '''获取y轴上可以有多少排敌人'''
    abailable_space_y = settings.screen_height - 3 * enemy_height - ship_height
    number_rows = int(abailable_space_y / (2 * enemy_height))
    return number_rows


def create_enemy(settings, screen, ship, enemys):
    '''创建敌人'''
    enemy = Enemy(settings, screen)
    enemy_width = enemy.rect.width
    number_enemy_x = get_number_enemy_x(settings, enemy_width)
    enemy_height = enemy.rect.height
    number_rows = get_number_rows(settings, enemy_height, ship.rect.height)
    for x in range(number_enemy_x):
        for y in range(number_rows):
            do_create_enemy(settings, screen, enemys, enemy_width, enemy_height, x, y)


def do_create_enemy(settings, screen, enemys, enemy_width, enemy_height, x, y):
    enemy = Enemy(settings, screen)
    enemy.x = enemy_width + 2 * enemy_width * x
    enemy.y = enemy_height + 2 * enemy_height * y
    enemy.rect.x = enemy.x
    enemy.rect.y = enemy.y
    enemys.add(enemy)


def change_enemy_move_direction(settings, enemys):
    '''改变敌人移动方向'''
    for e in enemys.sprites():
        e.rect.y += settings.enemy_drop_speed
    settings.enemy_move_direction *= -1

def check_enemy_edegs(settings,enemys):
    '''检测敌人是否到了边缘'''
    for e in enemys.sprites():
        if e.check_edges():
            change_enemy_move_direction(settings,enemys)
            break

def check_enemy_bottm(screen, settings, ship, bullets, enemys, stats, scoreboard):
    screen_rect = screen.get_rect()
    for e in enemys.sprites():
        if e.rect.bottom >= screen_rect.bottom:
            ship_hit(bullets,enemys,screen,settings,ship,stats,scoreboard)
            break

def update_enemy(screen,settings,ship,bullets,enemys,stats,scoreboard):
    check_enemy_edegs(settings,enemys)
    enemys.update()
    if pygame.sprite.spritecollideany(ship,enemys):
        ship_hit(bullets, enemys, screen, settings, ship, stats,scoreboard)
    check_enemy_bottm(screen,settings,ship,bullets,enemys,stats,scoreboard)

def ship_hit(bullets, enemys, screen, settings, ship, stats,scoreboard):
    if stats.ship_left > 0:
        print('Ship hit!')
        stats.ship_left -= 1
        scoreboard.prep_ships()
    else:
        stats.game_active = False
        pygame.mouse.set_visible(True)
        play_bg_music(False)

    enemys.empty()
    bullets.empty()
    create_enemy(settings, screen, ship, enemys)
    ship.center_ship()
    sleep(0.5)